﻿using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using FarseerGames.FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using System;

namespace AutumnEngine
{
    /// <summary>
    /// A sprite node with a physical body that reacts to gravity and other physic nodes.
    /// </summary>
    public class PhysicsSpriteNode : SpriteNode
    {
        float _width, _height;
        public PhysicsSpriteNode(string texture, BodyType type, float width, float height, float mass)
            : base(texture)
        {
            _width = width;
            _height = height;
            Type = type;
            Width = (int)width;
            Height = (int)height;

            switch (type)
            {
                case BodyType.Rectangular:
                    {
                        Body = BodyFactory.Instance.CreateRectangleBody(width, height, mass);
                        Geom = GeomFactory.Instance.CreateRectangleGeom(Body, width, height);
                        
                        Rotation = 0f;
                        break;
                    }

                case BodyType.Automatic:
                    {
                        //Not fully implemented.
                        uint[] data = new uint[this.Texture2D.Width * this.Texture2D.Height];
                        this.Texture2D.GetData(data);
                        
                        Vertices verts = Vertices.CreatePolygon(data, this.Texture2D.Width, this.Texture2D.Height);
                        Vector2 orig = verts.GetCentroid();
                        Body = BodyFactory.Instance.CreatePolygonBody(verts, mass);
                        Geom = GeomFactory.Instance.CreatePolygonGeom(Body, verts, 0);                            
                        break;
                    }
            }           
        }


        internal BodyType Type
        {
            get;
            private set;
        }

       
        

        public int Width
        {
            get;
            set;
        }

        public int Height
        {
            get;
            set;
        }

        public float Mass
        {
            get { return this.Body.Mass; }
            set { this.Body.Mass = value; }
        }

        /// <summary>
        /// Gets or sets the body.
        /// </summary>
        /// <value>The body.</value>
        public Body Body
        {
            get;
            set;
        }   

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="PhysicsSpriteNode"/> is static.
        /// </summary>
        /// <value><c>true</c> if static; otherwise, <c>false</c>.</value>
        public bool Static
        {
            get { return Body.IsStatic; }
            set { Body.IsStatic = value; }
        }

        /// <summary>
        /// Gets or sets the position.
        /// </summary>
        /// <value>The position.</value>
        public override Vector2 Position
        {
            get { return Body.Position; }
            set { Body.Position = value; }
        }

        /// <summary>
        /// Gets or sets the origin.
        /// </summary>
        /// <value>The origin.</value>
        public override Vector2 Origin
        {
            get
            {
                return new Vector2(_width / 2, _height / 2);
            }
            set
            {
                base.Origin = value;
            }
        }

        /// <summary>
        /// Gets the rotation.
        /// </summary>
        /// <value>The rotation.</value>
        public override float Rotation
        {
            get { return Body.Rotation; }
            set { Body.Rotation = value; }
        }

        /// <summary>
        /// Gets or sets the scale.
        /// </summary>
        /// <value>The scale.</value>
        public override Vector2 Scale
        {
            get
            {
                //Cannot change scale.
                return new Vector2(1f);
            }
            set
            {
                base.Scale = value;
            }
        }

        /// <summary>
        /// Gets or sets the geom.
        /// </summary>
        /// <value>The geom.</value>
        public Geom Geom
        {
            get;
            set;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public enum BodyType
    {
        /// <summary>
        /// A rectangular body.
        /// </summary>
        Rectangular = 0,
        Automatic = 1
    }
}
